<template>
  <div class="app-container">
    <!-- 条件查询 -->
    <el-form :model="queryParams" ref="queryForm" size="small" :inline="true" v-show="showSearch" label-width="68px">
      <el-form-item label="校区" prop="campusId">
        <el-select v-model="queryParams.campusId" placeholder="请选择校区" clearable @change="onCampusChange">
          <el-option
            v-for="item in campusOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
        />
        </el-select>
      </el-form-item>
      <el-form-item label="班级" prop="claId">
        <el-select v-model="queryParams.claId" placeholder="请选择班级" clearable :disabled="!queryParams.campusId">
          <el-option
            v-for="item in classOptions"
            :key="item.value"
            :label="item.label"
            :value="item.value"
          />
        </el-select>
      </el-form-item>
      <el-form-item>
        <el-button type="primary" icon="el-icon-search" size="mini" @click="handleQuery">查询课表</el-button>
        <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
      </el-form-item>
    </el-form>

    <!-- 课程信息展示 -->
    <div v-if="scheduleInfo" class="course-info">
      <el-descriptions title="课程信息" :column="4" border>
        <el-descriptions-item label="校区">{{ scheduleInfo.campusName }}</el-descriptions-item>
        <el-descriptions-item label="班级">{{ scheduleInfo.claDescribe }}</el-descriptions-item>
        <el-descriptions-item label="课程名称">{{ scheduleInfo.courseName }}</el-descriptions-item>
        <el-descriptions-item label="总课时">{{ scheduleInfo.totalCount }}</el-descriptions-item>
        <el-descriptions-item label="已上课时">{{ scheduleInfo.passNum || 0 }}</el-descriptions-item>
        <el-descriptions-item label="剩余课时">{{ (scheduleInfo.totalCount || 0) - (scheduleInfo.passNum || 0) }}</el-descriptions-item>
        <el-descriptions-item label="完成进度">
          <el-progress :percentage="Math.round(((scheduleInfo.passNum || 0) / (scheduleInfo.totalCount || 1)) * 100)"></el-progress>
        </el-descriptions-item>
        <el-descriptions-item label="操作">
        <el-button
          type="primary"
            size="small"
            icon="el-icon-magic-stick"
            @click="handleOneClickAdd"
            :disabled="!canUseOneClickAdd"
          >
            一键加课
          </el-button>
        </el-descriptions-item>
      </el-descriptions>
    </div>

    <!-- 课程表日历 -->
    <div class="calendar-container" v-if="scheduleInfo">
      <FullCalendar
        ref="fullCalendar"
        class="course-calendar"
        :options="calendarOptions"
      >
        <template v-slot:eventContent="arg">
          <div class="fc-event-content">
            <div class="fc-event-time">{{ arg.timeText }}</div>
            <div class="fc-event-title">{{ arg.event.title }}</div>
          </div>
        </template>
      </FullCalendar>
    </div>

    <!-- 空状态 -->
    <div v-if="!scheduleInfo && !loading" class="empty-state">
      <i class="el-icon-calendar"></i>
      <p>请选择校区和班级查看课程表</p>
      </div>

    <right-toolbar :showSearch.sync="showSearch" @queryTable="handleQuery"></right-toolbar>


  </div>
</template>

<script>
import FullCalendar from '@fullcalendar/vue'
import dayGridPlugin from '@fullcalendar/daygrid'
import interactionPlugin from '@fullcalendar/interaction'
import { getCampusOptions, getClassOptions, getCourseScheduleCalendar } from "@/api/course/courseLesson"
import { addCourseSchedule, batchAddCourseSchedule, delCourseSchedule, oneClickAddSchedule, getCourseSchedule, updateCourseSchedule, dragUpdateCourseDate } from "@/api/course/courseSchedule"

export default {
  name: "CourseLesson",
  components: {
    FullCalendar
  },
  data() {
    return {
      // 遮罩层
      loading: false,
      // 显示搜索条件
      showSearch: true,
      // 校区选项
      campusOptions: [],
      // 班级选项
      classOptions: [],
      // 课程表信息
      scheduleInfo: null,
      // 查询参数
      queryParams: {
        campusId: null,
        claId: null
      },

      // 日历配置
      calendarOptions: {
        plugins: [
          dayGridPlugin,
          interactionPlugin
        ],
        headerToolbar: {
          left: 'prev,next today',
          center: 'title',
          right: ''
        },
        initialView: 'dayGridMonth',
        locale: 'zh-cn',
        firstDay: 1, // 周一为第一天
        editable: true,
        selectable: true,
        selectMirror: true,
        dayMaxEvents: true,
        weekends: true,
        events: [],

        select: this.handleDateSelect,
        selectAllow: this.isSelectAllowed,
        dateClick: this.handleDateClick,
        eventClick: this.handleEventClick,
        eventDrop: this.handleEventDrop,
        eventResize: this.handleEventResize,
        eventAllow: this.isEventDropAllowed, // 控制事件拖拽的限制
        eventConstraint: {
          start: new Date().toISOString().split('T')[0] // 不能拖拽到今天之前
        },
        buttonText: {
          today: '今天'
        },
        moreLinkText: '更多',
        noEventsText: '暂无课程安排'
      }
    }
  },
  computed: {
    // 判断是否可以使用一键加课功能
    canUseOneClickAdd() {
      if (!this.scheduleInfo || !this.scheduleInfo.events) {
        return false
      }

      // 检查是否有可作为模板的课程（scheduleType为1或2）
      const hasTemplateSchedules = this.scheduleInfo.events.some(event => {
        return event.extendedProps && (event.extendedProps.scheduleType === '1' || event.extendedProps.scheduleType === '2')
      })

      // 检查剩余课时是否大于0
      const remainingHours = (this.scheduleInfo.totalCount || 0) - (this.scheduleInfo.passNum || 0)

      return hasTemplateSchedules && remainingHours > 0
    }
  },
  created() {
    this.loadCampusOptions()
  },
  methods: {
    /** 加载校区选项 */
    async loadCampusOptions() {
      try {
        const response = await getCampusOptions()
        this.campusOptions = response.data || []
      } catch (error) {
        console.error('加载校区选项失败:', error)
      }
    },

    /** 校区改变事件 */
    async onCampusChange(campusId) {
      this.queryParams.claId = null
      this.classOptions = []
      this.scheduleInfo = null

      if (campusId) {
        try {
          const response = await getClassOptions(campusId)
          this.classOptions = response.data || []
        } catch (error) {
          console.error('加载班级选项失败:', error)
        }
      }
    },

    /** 查询课表 */
    async handleQuery() {
      if (!this.queryParams.campusId || !this.queryParams.claId) {
        this.$modal.msgWarning('请先选择校区和班级')
        return
      }

      this.loading = true
      try {
        const response = await getCourseScheduleCalendar(this.queryParams)
        this.scheduleInfo = response.data

        if (this.scheduleInfo && this.scheduleInfo.events && this.scheduleInfo.events.length > 0) {
          console.log('加载的课程事件:', this.scheduleInfo.events)

          // 直接更新calendarOptions的events属性
          this.$set(this.calendarOptions, 'events', this.scheduleInfo.events)

          // 或者直接设置（两种方法都试试）
          this.calendarOptions = {
            ...this.calendarOptions,
            events: this.scheduleInfo.events
          }
        } else {
          console.log('没有找到课程事件数据')
          this.$set(this.calendarOptions, 'events', [])
        }
      } catch (error) {
        console.error('查询课程表失败:', error)
        this.$modal.msgError('查询课程表失败')
      } finally {
        this.loading = false
      }
    },

    /** 重置查询 */
    resetQuery() {
      this.queryParams = {
        campusId: null,
        claId: null
      }
      this.classOptions = []
      this.scheduleInfo = null
      this.calendarOptions.events = []
    },

    /** 日历日期选择事件 */
    async handleDateSelect(selectInfo) {
      if (!this.scheduleInfo) {
        this.$modal.msgWarning('请先选择班级')
        return
      }

      const calendarApi = selectInfo.view.calendar
      calendarApi.unselect() // 清除日期选择

      // 计算选中的日期范围
      const startDate = new Date(selectInfo.startStr.split('T')[0])
      const endDate = new Date(selectInfo.endStr.split('T')[0])

      // 检查是否选择了过去的日期
      const today = new Date()
      today.setHours(0, 0, 0, 0)
      startDate.setHours(0, 0, 0, 0)

      if (startDate <= today) {
        this.$modal.msgWarning('不能选择今天及之前的日期，请选择明天及以后的日期')
        return
      }

      // 如果是选择了多天，调整结束日期（FullCalendar的endStr是排他的，需要减一天）
      endDate.setDate(endDate.getDate() - 1)

      // 计算选中的天数
      const daysDiff = Math.round((endDate - startDate) / (1000 * 60 * 60 * 24)) + 1

      const dateRangeText = daysDiff === 1
        ? `选中日期：${this.formatDate(startDate)}`
        : `选中日期范围：${this.formatDate(startDate)} 至 ${this.formatDate(endDate)} (共${daysDiff}天)`

      // 弹出时间段选择对话框
      try {
        const timePeriod = await this.$prompt(
          `${dateRangeText}\n\n请输入课程时间段（如：09:00-11:30）`,
          '添加课程',
          {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            inputPattern: /^\d{1,2}:(00|30)-\d{1,2}:(00|30)$/,
            inputErrorMessage: '时间格式不正确，请输入如：09:00-11:30'
          }
        )

        // 如果是单天，直接添加
        if (daysDiff === 1) {
          const courseData = {
            lessonId: this.scheduleInfo.lessonId,
            claId: this.queryParams.claId,
            scheduleType: '2', // 手动添加
            specificDate: this.formatDate(startDate),
            timePeriod: timePeriod.value,
            status: '1'
          }

          await addCourseSchedule(courseData)
          this.$modal.msgSuccess('添加课程成功')
        } else {
          // 如果是多天，使用批量添加
          const batchData = {
            lessonId: this.scheduleInfo.lessonId,
            claId: this.queryParams.claId,
            specificDate: `${this.formatDate(startDate)}~${this.formatDate(endDate)}`,
            timePeriod: timePeriod.value
          }

          await batchAddCourseSchedule(batchData)
          this.$modal.msgSuccess(`批量添加课程成功，共添加${daysDiff}天`)
        }

        await this.handleQuery() // 刷新日历
      } catch (error) {
        if (error !== 'cancel') {
          console.error('添加课程失败:', error)
          // 显示后端返回的具体错误信息
          const errorMsg = error.response?.data?.msg || error.message || '添加课程失败'
          this.$modal.msgError(errorMsg)
        }
      }
    },

    /** 格式化日期为YYYY-MM-DD格式 */
    formatDate(date) {
      const year = date.getFullYear()
      const month = String(date.getMonth() + 1).padStart(2, '0')
      const day = String(date.getDate()).padStart(2, '0')
      return `${year}-${month}-${day}`
    },



    /** 判断日期是否允许选择（只允许选择明天及以后的日期） */
    isSelectAllowed(selectInfo) {
      const today = new Date()
      today.setHours(0, 0, 0, 0) // 设置为今天的00:00:00

      const selectDate = new Date(selectInfo.startStr)
      selectDate.setHours(0, 0, 0, 0) // 设置为选择日期的00:00:00

      // 只允许选择明天及以后的日期
      return selectDate > today
    },

    /** 判断事件拖拽是否允许 */
    isEventDropAllowed(dropInfo) {
      const today = new Date()
      today.setHours(0, 0, 0, 0)

      const targetDate = new Date(dropInfo.start)
      targetDate.setHours(0, 0, 0, 0)

      // 不允许拖拽到今天或过去的日期
      return targetDate > today
    },

    /** 处理日期单击事件 */
    handleDateClick(clickInfo) {
      // 不需要特殊处理，单击会自动触发select事件
      // 让handleDateSelect统一处理所有选择逻辑
    },

    /** 事件点击 */
    async handleEventClick(clickInfo) {
      // 检查是否点击了过去日期的课程
      const today = new Date()
      today.setHours(0, 0, 0, 0)

      const eventDate = new Date(clickInfo.event.startStr || clickInfo.event.start)
      eventDate.setHours(0, 0, 0, 0)

      if (eventDate <= today) {
        this.$modal.msgWarning('不能操作今天及之前日期的课程')
        return
      }

      // 弹出操作选择对话框
      const scheduleId = clickInfo.event.id || clickInfo.event.extendedProps.scheduleId
      const courseTitle = clickInfo.event.title

      if (!scheduleId) {
        this.$modal.msgWarning('无法获取课程信息')
        return
      }

      try {
        const action = await this.$confirm(
          `请选择对课程 '${courseTitle}' 的操作：`,
          '课程操作',
          {
            confirmButtonText: '编辑时间',
            cancelButtonText: '删除课程',
            distinguishCancelAndClose: true,
            type: 'info'
          }
        )

        // 用户选择了编辑
        if (action === 'confirm') {
          await this.handleEditSchedule(scheduleId, clickInfo.event)
        }
      } catch (action) {
        if (action === 'cancel') {
          // 用户选择了删除
          await this.handleDeleteSchedule(scheduleId, courseTitle)
        }
        // action === 'close' 时不做任何操作（用户点击了X关闭）
      }
    },

    /** 处理编辑课程安排 */
    async handleEditSchedule(scheduleId, eventObj) {
      try {
        // 获取课程详细信息
        const response = await getCourseSchedule(scheduleId)
        const scheduleData = response.data

        // 弹出编辑对话框
        const result = await this.showEditScheduleDialog(scheduleData)

        if (result) {
          // 更新课程安排
          await updateCourseSchedule(result)
          this.$modal.msgSuccess('修改成功')
          await this.handleQuery() // 刷新日历
        }
      } catch (error) {
        if (error !== 'cancel') {
          console.error('编辑失败:', error)
          this.$modal.msgError(error.response?.data?.msg || '编辑失败')
        }
      }
    },

    /** 处理删除课程安排 */
    async handleDeleteSchedule(scheduleId, courseTitle) {
      try {
        await this.$confirm(`确定要删除课程 '${courseTitle}' 吗？`, '删除确认', {
          confirmButtonText: '确定删除',
          cancelButtonText: '取消',
          type: 'warning'
        })

          await delCourseSchedule(scheduleId)
          this.$modal.msgSuccess('删除成功')
          await this.handleQuery() // 刷新日历
      } catch (error) {
        if (error !== 'cancel') {
          console.error('删除失败:', error)
          this.$modal.msgError(error.response?.data?.msg || '删除失败')
        }
      }
    },

    /** 显示编辑课程安排对话框 */
    showEditScheduleDialog(scheduleData) {
      return new Promise((resolve, reject) => {
        this.$prompt(
          `当前时间段：${scheduleData.timePeriod}\n请输入新的时间段：`,
          '编辑课程时间',
          {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            inputValue: scheduleData.timePeriod,
            inputPattern: /^([0-1]?[0-9]|2[0-3]):[0-5][0-9]-([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/,
            inputErrorMessage: '请输入正确的时间格式，如：09:00-12:00'
          }
        ).then(({ value }) => {
          if (value && value.trim()) {
            const updatedData = {
              ...scheduleData,
              timePeriod: value.trim()
            }
            resolve(updatedData)
          } else {
            reject('cancel')
          }
        }).catch(() => {
          reject('cancel')
        })
      })
    },

    /** 事件拖拽 */
    async handleEventDrop(dropInfo) {
      console.log('事件拖拽:', dropInfo)

      try {
        // 获取拖拽的课程信息
        const event = dropInfo.event
        const scheduleId = event.id || event.extendedProps.scheduleId

        if (!scheduleId) {
          this.$modal.msgError('无法获取课程信息')
          dropInfo.revert() // 恢复到原位置
          return
        }

        // 获取新的日期（格式化为 yyyy-MM-dd）
        const newDate = this.formatDateForAPI(dropInfo.event.start)

        // 检查是否拖拽到过去的日期
        const today = new Date()
        today.setHours(0, 0, 0, 0)

        const targetDate = new Date(dropInfo.event.start)
        targetDate.setHours(0, 0, 0, 0)

        if (targetDate <= today) {
          this.$modal.msgWarning('不能将课程拖拽到今天或过去的日期')
          dropInfo.revert() // 恢复到原位置
          return
        }

        // 确认拖拽操作
        const courseTitle = event.title
        const originalDate = this.formatDateForAPI(dropInfo.oldEvent.start)

        await this.$confirm(
          `确定要将课程 "${courseTitle}" 从 ${originalDate} 移动到 ${newDate} 吗？`,
          '确认拖拽',
          {
            confirmButtonText: '确定',
            cancelButtonText: '取消',
            type: 'info'
          }
        )

        // 准备更新数据
        const updateData = {
          scheduleId: parseInt(scheduleId),
          specificDate: newDate,
          // 保持其他字段不变，只更新日期
          lessonId: event.extendedProps.lessonId,
          claId: event.extendedProps.claId,
          timePeriod: event.extendedProps.timePeriod
        }

        // 调用拖拽更新API
        await dragUpdateCourseDate(updateData)

        this.$modal.msgSuccess('课程日期更新成功')

        // 刷新日历数据
        await this.handleQuery()

      } catch (error) {
        if (error !== 'cancel') {
          console.error('拖拽更新失败:', error)
          this.$modal.msgError(error.response?.data?.msg || '拖拽更新失败')
        }

        // 发生错误时恢复到原位置
        dropInfo.revert()
      }
    },

    /** 格式化日期为API需要的格式 */
    formatDateForAPI(date) {
      const d = new Date(date)
      const year = d.getFullYear()
      const month = String(d.getMonth() + 1).padStart(2, '0')
      const day = String(d.getDate()).padStart(2, '0')
      return `${year}-${month}-${day}`
    },

    /** 事件调整大小 */
    handleEventResize(resizeInfo) {
      console.log('事件调整大小:', resizeInfo)
      // 这里可以调用API更新课程时间
    },

    /** 创建事件ID */
    createEventId() {
      return String(Date.now())
    },

    /** 一键加课处理 */
    handleOneClickAdd() {
      if (!this.scheduleInfo) {
        this.$modal.msgError("请先选择班级")
        return
      }

      this.$modal.confirm('是否确认基于已有课程模式进行一键加课？系统将根据每节课的时长和剩余课时计算合适的课程节数。').then(() => {
        const params = {
          claId: this.queryParams.claId,
          lessonId: this.scheduleInfo.lessonId
        }

        oneClickAddSchedule(params).then(response => {
          this.$modal.msgSuccess(response.msg)
          // 重新加载课程表数据
          this.handleQuery()
        }).catch(error => {
          this.$modal.msgError(error.response?.data?.msg || "一键加课失败")
        })
      }).catch(() => {
        // 用户取消操作
      })
    },

    /** 格式化时间段 */
    formatTimePeriod(startStr, endStr) {
      const start = new Date(startStr)
      const end = new Date(endStr)

      const formatTime = (date) => {
        const hours = date.getHours().toString().padStart(2, '0')
        const minutes = date.getMinutes().toString().padStart(2, '0')
        return `${hours}:${minutes}`
      }

      return `${formatTime(start)}-${formatTime(end)}`
    },


  }
}
</script>

<style lang="scss" scoped>
.app-container {
  .course-info {
    margin-bottom: 20px;
  }

  .calendar-container {
    background: white;
    padding: 20px;
    border-radius: 4px;
    box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  }

  .course-calendar {
    max-width: 100%;
    margin: 0 auto;
  }

  .empty-state {
    text-align: center;
    padding: 60px 0;
    color: #909399;

    i {
      font-size: 48px;
      margin-bottom: 20px;
      display: block;
    }

    p {
      font-size: 16px;
      margin: 0;
    }
  }
}

// FullCalendar 样式自定义
:deep(.fc) {
  .fc-toolbar-title {
    font-size: 1.5em;
    color: #303133;
  }

  .fc-button-primary {
    background-color: #409EFF;
    border-color: #409EFF;

    &:hover {
      background-color: #66b1ff;
      border-color: #66b1ff;
    }

    &:focus {
      box-shadow: 0 0 0 0.2rem rgba(64, 158, 255, 0.25);
    }
  }

  .fc-event {
    border-radius: 4px;
    border: none;
    padding: 2px 4px;
    cursor: pointer;
    transition: all 0.2s ease;

    .fc-event-content {
      .fc-event-time {
        font-weight: bold;
        font-size: 0.9em;
      }

      .fc-event-title {
        font-size: 0.85em;
        margin-top: 2px;
      }
    }

    // 正常情况下的悬停效果
    &:hover {
      transform: scale(1.02);
      box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
    }

    // 拖拽时的样式
    &.fc-event-dragging {
      opacity: 0.8;
      transform: scale(1.05);
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
      z-index: 1000;
    }
  }

  // 过去日期中的事件样式
  .fc-day-past .fc-event {
    background-color: #f5f5f5 !important;
    border-color: #dcdfe6 !important;
    color: #909399 !important;
    cursor: not-allowed !important;
    opacity: 0.6;
    pointer-events: none; // 禁用所有鼠标事件

    &:hover {
      background-color: #f5f5f5 !important;
      transform: none !important;
      box-shadow: none !important;
    }

    // 确保拖拽时不会改变样式
    &.fc-event-dragging {
      opacity: 0.6 !important;
      transform: none !important;
      box-shadow: none !important;
    }
  }

  .fc-daygrid-event {
    font-size: 0.8em;
  }

  .fc-timegrid-event {
    font-size: 0.85em;
  }

  // 过去日期的样式
  .fc-day-past {
    background-color: #f5f5f5 !important;
    color: #c0c4cc !important;
    cursor: not-allowed !important;

    &:hover {
      background-color: #f5f5f5 !important;
    }
  }

  // 今天的样式
  .fc-day-today {
    background-color: #fdf6ec !important;
    border: 1px solid #e6a23c !important;

    .fc-daygrid-day-number {
      color: #e6a23c;
      font-weight: bold;
    }
  }
}
</style>
